home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / gs24src.zip / NPACKED.H < prev    next >
C/C++ Source or Header  |  1992-03-01  |  5KB  |  110 lines

  1. /* Copyright (C) 1991, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* packed.h */
  21. /* Packed array format for Ghostscript */
  22.  
  23. /*
  24.  
  25. Packed elements come in 2 different sizes, 2 bytes or 8 bytes.  The
  26. top bits of the first 16-bit subelement distinguish the 2 forms.  The
  27. 'size' of a packed array is the number of elements, not the number of
  28. bytes it occupies.  The encoding:
  29.  
  30.     00--tttt texrwsnm    full 8-byte object
  31.     01m0jjjj jjjjjjjj    executable operator (for bind)
  32.     01m1vvvv vvvvvvvv    integer (biased by packed_min_intval)
  33.     10miiiii iiiiiiii    literal name
  34.     11miiiii iiiiiiii    executable name
  35.  
  36. The m bit is the mark bit for the garbage collector.  Note its
  37. slightly unusual placement.
  38.  
  39. The jjj index of executable operators is either the index of the
  40. operator in the op_def_table, if the index is less than op_def_count,
  41. or the index of the definition in the op_array_table (subtracting
  42. op_def_count first).
  43.  
  44. The iii index of names is the one that the name machinery already
  45. maintains.  A name whose index is larger than will fit in the packed
  46. representation must be represented as a full 8-byte element.
  47.  
  48. There are actually two packed array types, t_mixedarray and
  49. t_shortarray.  A t_mixedarray can have a mix of 2- and 8-bit
  50. elements; a t_shortarray has all 2-byte elements.  In both cases, the
  51. `size' is the number of elements.
  52.  
  53. Packed array elements can be distinguished from full-size elements,
  54. so we allow the interpreter to simply execute all the different kinds
  55. of arrays directly.  In theory, this could lead to unaligned accesses
  56. to full-size (8-byte) refs.  Some machines can't handle unaligned
  57. accesses of this kind.  Rather than try to tailor the algorithms to
  58. the machine's capabilities, we guarantee that full-size elements in
  59. mixed arrays are always properly aligned.  We do this by converting
  60. up to 3 preceding 2-byte elements into 8-byte elements so that the
  61. alignment is preserved.  The only code this actually affects is in
  62. make_packed_array.  However, the save/restore machinery in isave.c is
  63. sometimes used to save changes to packed arrays, and it currently
  64. only knows how to save full-size, aligned refs.
  65.  
  66. Note that code in zpacked.c and interp.c knows more about the
  67. representation of packed elements than the definitions in this file
  68. would imply.  Read the code carefully if you change the
  69. representation.
  70.  
  71.  */
  72.  
  73. typedef ushort ref_packed;
  74.  
  75. #define packed_type_shift 12
  76. typedef enum {
  77.     pt_full_ref = 0,
  78. #define pt_min_packed 4
  79.     pt_executable_operator = 4,
  80.     pt_integer = 5,
  81.     pt_literal_name = 8,
  82.     pt_executable_name = 12
  83. } packed_type;
  84. #define pt_tag(pt) ((ref_packed)(pt) << packed_type_shift)
  85. #define r_is_packed(rp)  (*(ref_packed *)(rp) >= pt_tag(pt_min_packed))
  86. #define packed_ref_is_name(prp) (*(prp) >= pt_tag(pt_literal_name))
  87. #define packed_max_full_ref (pt_tag(pt_min_packed) - 1)
  88. #define packed_min_intval (-(1 << (packed_type_shift - 1)))
  89. #define packed_max_intval ((1 << (packed_type_shift - 1)) - 1)
  90. #define packed_int_mask ((1 << packed_type_shift) - 1)
  91. #define packed_max_name_index ((1 << (packed_type_shift + 1)) - 1)
  92. #define packed_per_ref (sizeof(ref) / sizeof(ref_packed))
  93.  
  94. /* Packed ref marking */
  95. #define lp_mark 0x2000
  96. #define r_has_pmark(rp) (*(rp) & lp_mark)
  97. #define r_set_pmark(rp) (*(rp) |= lp_mark)
  98. #define r_clear_pmark(rp) (*(rp) &= ~lp_mark)
  99.  
  100. /* Procedures implemented in zpacked.c */
  101.  
  102. /* Make a packed array */
  103. extern    int    make_packed_array(P4(ref *, uint, ref *, char *));
  104.  
  105. /* Get an element from a packed array. */
  106. extern    void    packed_get(P2(ref_packed *, ref *));
  107. /* Advance to the next element in a packed array. */
  108. #define packed_next(packed)\
  109.   (*packed <= packed_max_full_ref ? packed + packed_per_ref : packed + 1)
  110.